package org.system.core.service.system;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.system.core.domain.entity.SysDictData;
import org.system.core.domain.entity.SysDictType;
import org.system.core.exception.ServiceException;
import org.system.core.mapper.system.SysDictDataMapper;
import org.system.core.mapper.system.SysDictTypeMapper;
import org.system.core.utils.MessageUtils;
import org.system.core.utils.SecurityUtils;
import org.system.core.utils.StringUtils;
import org.system.core.utils.dict.DictUtils;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author baoRoot
 */
@Service
public class SysDictTypeService {

    @Autowired
    private SysDictTypeMapper sysDictTypeMapper;
    @Autowired
    private SysDictDataMapper sysDictDataMapper;

    public List<SysDictType> selectDictTypeList(SysDictType dictType) {
        return sysDictTypeMapper.selectDictTypeList(dictType);
    }

    public SysDictType selectDictTypeById(Long dictId) {
        return sysDictTypeMapper.selectDictTypeById(dictId);
    }

    public boolean checkDictTypeUnique(SysDictType dict) {
        Long dictId = StringUtils.isNull(dict.getDictId()) ? -1L : dict.getDictId();
        SysDictType dictType = sysDictTypeMapper.checkDictTypeUnique(dict.getDictType());
        return !StringUtils.isNotNull(dictType) || dictType.getDictId().longValue() == dictId.longValue();
    }

    public void insertDictType(SysDictType dictType) {
        if(!checkDictTypeUnique(dictType)) {
            throw new ServiceException(MessageUtils.message("system.dict.exist_error"));
        }
        dictType.setCreateBy(SecurityUtils.getUsername());
        if (sysDictTypeMapper.insertDictType(dictType) <= 0) {
            throw new ServiceException(MessageUtils.message("system.monitor.add_error"));
        }
        DictUtils.setDictCache(dictType.getDictType(),null);
    }

    @Transactional
    public void updateDictType(SysDictType dict) {
        checkDictTypeUnique(dict);
        dict.setUpdateBy(SecurityUtils.getUsername());
        SysDictType oldDict = sysDictTypeMapper.selectDictTypeById(dict.getDictId());
        sysDictDataMapper.updateDictDataType(oldDict.getDictType(), dict.getDictType());
        if(sysDictTypeMapper.updateDictType(dict) <= 0) {
            throw new ServiceException(MessageUtils.message("system.monitor.edit_error"));
        }
        List<SysDictData> dictDatas = sysDictDataMapper.selectDictDataByType(dict.getDictType());
        DictUtils.setDictCache(dict.getDictType(), dictDatas);
    }

    public void deleteDictTypeByIds(Long[] dictIds) {
        for (Long dictId : dictIds) {
            SysDictType dictType = selectDictTypeById(dictId);
            if (sysDictDataMapper.countDictDataByType(dictType.getDictType()) > 0) {
                throw new ServiceException(String.format("%1$s已分配,不能删除", dictType.getDictName()));
            }
            if (sysDictTypeMapper.deleteDictTypeById(dictId) <= 0) {
                throw new ServiceException(MessageUtils.message("system.monitor.delete_error"));
            }
            DictUtils.removeDictCache(dictType.getDictType());
        }
    }

    public void clearDictCache() {
        DictUtils.clearDictCache();
    }

    public void resetDictCache() {
        clearDictCache();
        loadingDictCache();
    }

    public void loadingDictCache() {
        SysDictData dictData = new SysDictData();
        dictData.setStatus("0");
        Map<String, List<SysDictData>> dictDataMap = sysDictDataMapper.selectDictDataList(dictData).stream().collect(Collectors.groupingBy(SysDictData::getDictType));
        for (Map.Entry<String, List<SysDictData>> entry : dictDataMap.entrySet()) {
            DictUtils.setDictCache(entry.getKey(), entry.getValue().stream().sorted(Comparator.comparing(SysDictData::getDictSort)).collect(Collectors.toList()));
        }
    }

    public List<SysDictType> selectDictTypeAll() {
        return sysDictTypeMapper.selectDictTypeAll();
    }

}
